iT邦幫忙

2022 iThome 鐵人賽

DAY 29
0
Mobile Development

Flutter Developer Learning SwiftUI系列 第 29

Flutter Developer Learning SwiftUI. @State var lesson29 = "環境變數"

  • 分享至 

  • xImage
  •  

Today Preview

Yes

本來是想講講有哪些常用的內建EnvironmentValues
甚至是有哪些常用的property wrapper
但還是算了= =

今天就Demo一下

  1. 透過@Environment讀取colorScheme
  2. 自訂EnvironmentKey&EnvironmentValues
  3. 如何使用@EnvironmentObject

...也是不少了

1. colorScheme

首先我發現要改淺/深色模式是用.preferredColorScheme()這個modifier
但是它會“感染”到整個app
餵了一下狗發現還有另外一個modifier可以只改單個View
就是.colorScheme()
但他有以下限制

  1. 不能改背景
  2. 優先權比preferredColorScheme高
  3. 已棄用= =

EDIT: 寫文章時發現原來用.environment(.colorScheme, .dark)就可以很輕易地改單個View了,囧
詳見

2. @Environment

這個wrapper我們以前就有用過了
SwiftUI會提供一些內建的環境變數給我們讀取/使用
最常看到的是.presentationMode(但已被.dismiss取代)
而我們也可以用.colorScheme來判斷目前是在淺色還是深色模式
但它只能偵測.preferredColorScheme()的改變
.colorScheme()是不行的

3. Custom Environment Values

上一節提到SwiftUI有內建一些變數給我們了
那麼我們是不是也可以自訂變數來用呢?
答案是肯定的
總共有兩個步驟

  1. 新建一個struct comform EnvironmentKey
    必須有型別屬性defaultValue
  2. extension EnvironmentValues,新增一個屬性,就是我們之後要存取的環境變數
    裡面的get/set就是用到剛剛新建的EnvironmentKey

讀取的話一樣是用之前的@Environment
而寫入的話是用.environment()這個modifier
官方範例在這
但@Environment由下而上只能讀取,你在這層做的改變,只會從下層開始影響
如果想要自由(?)一點,就要用到下節說的@EnvironmentObject

4. @EnvironmentObject

要使用大逆不道的@EnvironmentObject
首先要用到我們最後一堂課才終於遇見的class
這個class必須comform ObservableObject(公眾人物)
裡面的屬性就是我們關心的資料,則要用@Published修飾(昭告天下)
接著用.environmentObject()這modifier注入
@EnvironmentObject就可以取得object,愛怎麼改就怎麼改了XD

那麼為什麼我們一開始說這玩意是大逆不道呢?
請見來自前輩的警告
其實我是覺得這東西跟Flutter的provider或BLoC滿像的☘️☘️☘️
都是用來一鍵改變整個app的東西
可以用改修改app的語系啦風格主題啦
應該是滿適合的
然後副作用是用了@EnvironmentObject之後
在XXX_Previews裡面也要用.environmentObject()注入一下
不然無法預覽= =

5. 範例說明


主要分成上下兩個部分
上半部橘色是觀察與控制colorScheme
第一個Toggle是綁定isCurrentPageDarkMode與更新.colorScheme()
第二個Toggle是綁定isWholeAppDarkMode與更新.preferredColorScheme()
然後為了解決.colorScheme()權重比.preferredColorScheme()高的問題
我在.onChange()用isWholeAppDarkMode覆寫isCurrentPageDarkMode

下半部藍色可以再分成兩個view
紅色是目前這個view
綠色是另外拆出來的subView
然後各自都觀察@Environment 跟 @EnvironmentObject 的影響
結果就是第一個Toggle只能改變subView是否紅字
而第二個Toggle不只這層下層,甚至連上層是否紅字都能掌控

詳細代碼請見以下截圖



6. 最後送點小禮物

開頭發的宏願
請見下方三個驚人連結(竟然還有人出了專門的網站XD)
SwiftUI Property Wrappers
[HACKING WITH SWIFT] Which SwiftUI property wrapper to choose in any situation
[HACKING WITH SWIFT] All SwiftUI property wrappers explained and compared

Tomorrow Preview

精彩大結局


https://github.com/mark33699/FDLS


上一篇
Flutter Developer Learning SwiftUI. @State var lesson28 = "多平台"
下一篇
Flutter Developer Learning SwiftUI. @State var lesson30 = "總複習"
系列文
Flutter Developer Learning SwiftUI30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言